//! 单线程存储架构设计方案
//! 
//! 参考 Redis 官方设计，去除复杂的锁机制，提供高性能单线程存储

use crate::error::{Result, StorageError};
use crate::storage::data_types::*;
use fxhash::FxHashMap;
use std::time::{Duration, SystemTime};

/// 简化的单线程存储引擎 (使用高性能 FxHashMap)
pub struct SimpleStorage {
    data: FxHashMap<String, Box<dyn DataType>>,
    ttl_data: FxHashMap<String, SystemTime>,
}

impl SimpleStorage {
    pub fn new() -> Self {
        Self {
            data: FxHashMap::default(),
            ttl_data: FxHashMap::default(),
        }
    }

    /// SET 命令 - 直接操作，无锁
    pub fn set(&mut self, key: String, value: String) -> Result<()> {
        let string_type = Box::new(StringType::new(value));
        self.data.insert(key, string_type);
        Ok(())
    }

    /// GET 命令 - 直接访问，无锁
    pub fn get(&self, key: &str) -> Result<Option<String>> {
        // 检查是否过期
        if self.is_expired(key) {
            return Ok(None);
        }

        match self.data.get(key) {
            Some(data_type) => {
                if let Some(string_type) = data_type.as_any().downcast_ref::<StringType>() {
                    Ok(Some(string_type.get().to_string()))
                } else {
                    Err(StorageError::TypeMismatch {
                        expected: "string".to_string(),
                        found: data_type.type_name().to_string(),
                    })
                }
            }
            None => Ok(None),
        }
    }

    /// INCR 命令 - 直接修改，无锁
    pub fn incr_by(&mut self, key: &str, amount: i64) -> Result<i64> {
        match self.data.get_mut(key) {
            Some(data_type) => {
                if let Some(string_type) = data_type.as_any_mut().downcast_mut::<StringType>() {
                    string_type.increment(amount)
                } else {
                    Err(StorageError::TypeMismatch {
                        expected: "string".to_string(),
                        found: data_type.type_name().to_string(),
                    })
                }
            }
            None => {
                let mut string_type = StringType::new(amount.to_string());
                let result = string_type.increment(0)?; // 获取当前值
                self.data.insert(key.to_string(), Box::new(string_type));
                Ok(result)
            }
        }
    }

    /// HSET 命令 - 直接操作，无锁
    pub fn hset(&mut self, key: &str, field: String, value: String) -> Result<bool> {
        match self.data.get_mut(key) {
            Some(data_type) => {
                if let Some(hash_type) = data_type.as_any_mut().downcast_mut::<HashType>() {
                    hash_type.hset(field, value)
                } else {
                    Err(StorageError::TypeMismatch {
                        expected: "hash".to_string(),
                        found: data_type.type_name().to_string(),
                    })
                }
            }
            None => {
                let mut hash_type = HashType::new();
                let result = hash_type.hset(field, value)?;
                self.data.insert(key.to_string(), Box::new(hash_type));
                Ok(result)
            }
        }
    }

    /// 删除过期key的清理
    pub fn cleanup_expired_keys(&mut self) -> usize {
        let now = SystemTime::now();
        let mut expired_keys = Vec::new();

        for (key, expire_time) in &self.ttl_data {
            if now >= *expire_time {
                expired_keys.push(key.clone());
            }
        }

        for key in &expired_keys {
            self.data.remove(key);
            self.ttl_data.remove(key);
        }

        expired_keys.len()
    }

    /// 检查key是否过期
    fn is_expired(&self, key: &str) -> bool {
        if let Some(expire_time) = self.ttl_data.get(key) {
            SystemTime::now() >= *expire_time
        } else {
            false
        }
    }

    /// 设置TTL
    pub fn expire(&mut self, key: &str, seconds: u64) -> bool {
        if self.data.contains_key(key) {
            let expire_time = SystemTime::now() + Duration::from_secs(seconds);
            self.ttl_data.insert(key.to_string(), expire_time);
            true
        } else {
            false
        }
    }
}

/// 单线程命令处理器
pub struct SingleThreadCommandProcessor {
    storage: SimpleStorage,
}

impl SingleThreadCommandProcessor {
    pub fn new() -> Self {
        Self {
            storage: SimpleStorage::new(),
        }
    }

    /// 处理命令 - 单线程，按顺序执行
    pub fn process_command(&mut self, command: &str, args: Vec<String>) -> Result<String> {
        match command.to_uppercase().as_str() {
            "SET" => {
                if args.len() != 2 {
                    return Err(StorageError::InvalidArgument {
                        message: "SET requires exactly 2 arguments".to_string(),
                    });
                }
                self.storage.set(args[0].clone(), args[1].clone())?;
                Ok("OK".to_string())
            }
            "GET" => {
                if args.len() != 1 {
                    return Err(StorageError::InvalidArgument {
                        message: "GET requires exactly 1 argument".to_string(),
                    });
                }
                match self.storage.get(&args[0])? {
                    Some(value) => Ok(value),
                    None => Ok("(nil)".to_string()),
                }
            }
            "INCR" => {
                if args.len() != 1 {
                    return Err(StorageError::InvalidArgument {
                        message: "INCR requires exactly 1 argument".to_string(),
                    });
                }
                let result = self.storage.incr_by(&args[0], 1)?;
                Ok(result.to_string())
            }
            "HSET" => {
                if args.len() != 3 {
                    return Err(StorageError::InvalidArgument {
                        message: "HSET requires exactly 3 arguments".to_string(),
                    });
                }
                let created = self.storage.hset(&args[0], args[1].clone(), args[2].clone())?;
                Ok(if created { "1" } else { "0" }.to_string())
            }
            _ => Err(StorageError::InvalidArgument {
                message: format!("Unknown command: {}", command),
            })
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_single_thread_performance() {
        let mut processor = SingleThreadCommandProcessor::new();
        let start = std::time::Instant::now();

        // 执行10000个命令
        for i in 0..10000 {
            processor.process_command("SET", vec![format!("key_{}", i), format!("value_{}", i)]).unwrap();
            processor.process_command("GET", vec![format!("key_{}", i)]).unwrap();
            processor.process_command("INCR", vec![format!("counter_{}", i)]).unwrap();
        }

        let elapsed = start.elapsed();
        println!("单线程处理30000个命令耗时: {:?}", elapsed);
        println!("平均每个命令: {:?}", elapsed / 30000);
    }

    #[test]
    fn test_simple_operations() {
        let mut processor = SingleThreadCommandProcessor::new();

        // SET/GET
        assert_eq!(processor.process_command("SET", vec!["key1".to_string(), "value1".to_string()]).unwrap(), "OK");
        assert_eq!(processor.process_command("GET", vec!["key1".to_string()]).unwrap(), "value1");

        // INCR
        assert_eq!(processor.process_command("INCR", vec!["counter".to_string()]).unwrap(), "1");
        assert_eq!(processor.process_command("INCR", vec!["counter".to_string()]).unwrap(), "2");

        // HSET
        assert_eq!(processor.process_command("HSET", vec!["hash1".to_string(), "field1".to_string(), "hvalue1".to_string()]).unwrap(), "1");
    }
}